#include "ControlSystem.h"
#include "../input/InputSystem.h"
#include "../draw/DrawSystem.h"
#include "../tools/Log.h"
#include "../game/GameControl.h"
#include "../tools/Time.h"

#include <assert.h>
#include <cstdlib>

ControlSystem::ControlSystem(): InputInterface(), gui(), args(NULL), gameInstance(NULL) {}
ControlSystem::~ControlSystem() { if(gameInstance) { delete gameInstance; gameInstance = NULL; } }

static bool ok = true;
bool ControlSystem::isOk() {	return ok; }
void ControlSystem::setOk(bool b) { ok = b; }

void ControlSystem::onWindowResize(float W, float H)
{
// Dispatch to all members that need to know about this
	gui.onWindowResize(W, H);
	if(gameInstance != NULL)
		gameInstance->onWindowResize(W,H);
}

void ControlSystem::changeGUIto(std::string& s)
{
	gui.switchToFrame(s);
// Unsure if resetting the focus is appropriate here
	InputSystem::Instance().setFocus(this);
}

void ControlSystem::createGame(const GameConf& game_conf)
{
	gui.disable();
	assert(gameInstance == NULL);
	gameInstance = new GameControl();	
	gameInstance->init(game_config_file, game_conf);
}

void ControlSystem::destroyGame()
{
	assert(gameInstance != NULL);
	delete gameInstance;
	gameInstance = NULL;
	gui.enable();
}

void ControlSystem::exitApp()
{
//	std::exit(0);
	setOk(false);
}

void ControlSystem::disableGUI() {
	gui.disable();
}

void ControlSystem::update(long)
{
	static unsigned long currTime = getMilliseconds();
	unsigned long dt = getMilliseconds() - currTime;

	DrawSystem::Instance().update(dt);
	InputSystem::Instance().update();
	
	currTime += dt;
}

bool ControlSystem::init(const CmdLineArgs& cmdArgs)
{
	if(!InputSystem::Instance().init(cmdArgs))	return false;
	if(!DrawSystem::Instance().init(cmdArgs))	return false;
	
	args = const_cast <CmdLineArgs*> (&cmdArgs);
	
	// TODO Read both of these values from an xml file (config.xml)
	gui.load("conf/menu.xml");				// Load main menu
	game_config_file = "conf/game.xml";		// File in which building types, unit types, etc. are specified
	
	InputSystem::Instance().setFocus(this);
	
	gui.enable();
	return true;
}

void ControlSystem::kill()
{
	if(gameInstance)
	{
		delete gameInstance;
		gameInstance = NULL;
	}
	
	gui.disable();
	gui.kill();
	
	InputSystem::Instance().kill();
	DrawSystem::Instance().kill();
}

void ControlSystem::terminate()
{
	if(gameInstance)
	{
		delete gameInstance;
		gameInstance = NULL;
	}
	
	gui.kill();
	
	InputSystem::Instance().terminate();
	DrawSystem::Instance().terminate();
	
	lout << endl << "Terminating..." << endl;
}

//Dispatch all input we receive straight to the gui
void ControlSystem::onMouseButtonDown(KEY_TYPE k, int x, int y)	{	gui.onMouseButtonDown(k,x,y);	}
void ControlSystem::onMouseButtonUp(KEY_TYPE k, int x, int y)	{	gui.onMouseButtonUp(k,x,y);	}

void ControlSystem::onKeyDown(KEY_TYPE k)	{	gui.onKeyDown(k);	}
void ControlSystem::onKeyUp(KEY_TYPE k)		{	gui.onKeyUp(k);	}

void ControlSystem::onMouseMove(int x, int y)	{	gui.onMouseMove(x,y);	}


